﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace System8Equations
{
    /// <summary>
    /// Very simple class that we can use to move through all the
    /// values we are going to run. Should e totally random, and if we don't use
    ///
    /// </summary>
    public abstract class S8Variable : IEnumerable<double>
    {
        /// <summary>
        /// Get/Set the variable path of what we are planning on varrying.
        /// </summary>
        public string Path { get; set; }

        /// <summary>
        /// Gets the next value in the sequence
        /// </summary>
        /// <returns></returns>
        protected abstract double GetValue();

        /// <summary>
        /// Moves through the code!
        /// </summary>
        /// <returns></returns>
        public IEnumerator<double> GetEnumerator()
        {
            while (true)
            {
                yield return GetValue();
            }
        }

        /// <summary>
        /// Returns the path, correctly formatted.
        /// </summary>
        /// <returns></returns>
        public override string ToString()
        {
            string result = Path.Replace('/', '.');
            if (result.EndsWith("Value"))
            {
                result = result.Substring(0, result.Length - 5);
            }
            return result;
        }

        /// <summary>
        /// The variable we are "simulating" has a new central value. Update ourselves to reflect that.
        /// </summary>
        /// <param name="newCentralValue"></param>
        public abstract void Update(double newCentralValue);

        /// <summary>
        /// Fired when somethign about us changes
        /// </summary>
        public event Action<S8Variable> ValueChanged;

        /// <summary>
        /// Fire off the value changed event
        /// </summary>
        protected void OnValueChanged()
        {
            if (ValueChanged != null)
            {
                ValueChanged(this);
            }
        }

        #region IEnumerable Members

        System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
        {
            throw new NotImplementedException();
        }

        #endregion
    }
}
